<?php
/**
 * Auther: Joshua Conero
 * Date: 2017/6/21 0021 23:49
 * Email: brximl@163.com
 * Name:
 */

namespace app\api\controller;


use app\common\controller\Api;
use app\common\model\Fnc1000c;
use app\common\model\Fnc1001c;
use hyang\Util;
use think\Db;

class Faccount extends Api
{
    // 数据保存
    // 可传入与数据库相符合的字段，以及附加字段 【add_check】
    public function save(){
        $check = $this->needLoginNet($uid);
        if($check) return $check;
        list($data,$mode,$map) = $this->_getSaveData('no');
        $addCheck = ($data['add_check'] ?? false);
        $data = Util::dataUnset($data,['master']);
        $tagList = Util::getKeyAndDel('tags', $data);  // 标签列表
        $fnc = new Fnc1000c();
        $data = Util::dataClear($data,['tag_id','slave_id','subject_id','src_plan_no']);
        if($mode == 'A'){
            $data['uid'] = $uid;
            // 重复性账单提醒
            if(!$addCheck){
                $bSlaveId = (empty($data['slave_id'] ?? null)? 'null': $data['slave_id']);
                $bSlave = (empty($data['slave'] ?? null)? 'null': '\''.$data['slave'].'\'');
                $whStr = 'ifnull(master_id, 1)=ifnull(:master_id, 1) and 
                    ifnull(slave_id, -1)=ifnull('.$bSlaveId.', -1) and 
                    ifnull(slave, \'\')=ifnull('.$bSlave.', \'\') and
                    (money - '.$data['money'].') = 0
                    ';
                // @tip tp5.1 数据绑定是 null 类型被当做空字符串
                $whBind = [
                    'master_id' => $data['master_id'],
                    //'slave_id' => (empty($data['slave_id'] ?? null)? null: $data['slave_id']),
                    //'slave' => (empty($data['slave'] ?? null)? null: $data['slave']),
                    //'money' => intval($data['money']),
                ];
                $hasNo = $fnc->where([
                        'date' => $data['date'],
                        'type' => $data['type'],
                        'subject_id' => $data['subject_id']
                    ])
                    ->whereRaw($whStr, $whBind)
                    ->value('no')
                ;
                if($hasNo){
                    return $this->FeekMsg(['msg' => '您的账单可能已经存在，请确认?', 'add_check' => 1, 'code' => -1], -1);
                }
            }

            $data['no'] = $fnc->getNoVal();
            if($fnc->save($data)){
                $fnc->tagSave($tagList);
                return $this->FeekMsg('记账成功！',1);
            }
            return $this->FeekMsg('记账失败！');
            //debugOut($data);
        }elseif ($mode == 'M'){
            $fnc->no = $map['no'];
            if($fnc->save($data,$map)) {
                $fnc->tagSave($tagList);
                return $this->FeekMsg('账单更新成功！',1);
            }
            return $this->FeekMsg('账单更新失败！');
        }elseif ($mode == 'D'){
            $fnc->removeTags($map['no']);
            if($this->pushRptBack($fnc->getTable(),$map,'auto')){
                return $this->FeekMsg('账单删除成功！',1);
            }
            return $this->FeekMsg('账单删除失败！');
        }
        return $this->FeekMsg('系统请求失败！');
    }
    // 明细数据保存
    public function detail(){
        $check = $this->needLoginNet($uid);
        if($check) return $check;
        list($data,$mode,$map) = $this->_getSaveData('no');
        $fnc = new Fnc1001c();
        if($mode == 'A'){
            // 唯一性检测
            if($fnc->where(['src_no'=>$data['src_no'],'name'=>$data['name']])->count()){
                return $this->FeekMsg('【'.$data['name'].'】账单明细已经存在！');
            }
            $data['no'] = $fnc->getNoVal();
            if($fnc->save($data)) return $this->FeekMsg('账单明细新增成功！',1);
            return $this->FeekMsg('账单明细新增！');
        }elseif ($mode == 'M'){
            if($fnc->save($data,$map)) return $this->FeekMsg('账单明细更新成功！',1);
            return $this->FeekMsg('账单明细更新失败！');
        }elseif ($mode == 'D'){
            if($this->pushRptBack($fnc->getTable(),$map,'auto')) return $this->FeekMsg('账单明细新增成功！',1);
            return $this->FeekMsg('账单明细新增失败！');
        }
        return $this->FeekMsg('系统请求失败！');
    }
    // 明细数据同步财务账单
    public function detailSync(){
        $check = $this->needLoginNet($uid);
        if($check) return $check;
        $no = request()->param('no');
        if($no){
            $field = 'SUM(money*`part`)';
            $amount = Fnc1001c::where('src_no', $no)
                //->sum('`money`*`amount`')
                ->field($field)
                //->find()
                ->value($field)
                ;
            if($amount){
                $model = Fnc1000c::where('no', $no)->find();
                if($model){
                    $model->money = $amount;
                    if($model->save()){
                        return $this->FeekMsg('数据同步成功！', 1);
                    }
                }
                return $this->FeekMsg('数据同步失败，可能明细不存在！');
            }
            return $this->FeekMsg('数据同步失败！');
        }
        return $this->FeekMsg('数据请求无效');
    }
    // 单条明细账
    // 参数： no * -> json
    public function get_detail(){
        $no = request()->param('no');
        if($no){
            $rs = (new Fnc1001c())->get($no)->toArray();
            return $this->FeekMsg($rs);
        }
        return $this->FeekMsg('请求参数无效！');
    }
    /**
     * 获取财务账单
     * 请求参数： page: 页码, num: 单列显示数
     */
    public function sets(){
        $check = $this->needLoginNet($uid);
        if($check) return $check;
        $page = request()->param('page');
        $num = request()->param('num');
        $page = is_numeric($page)? intval($page): 1;
        $num = is_numeric($num)? intval($num): 20;
        $group = request()->param('group');
        $ss = bsjson(request()->param('ss'));
        $where = request()->param('where');
        //debugOut($ss);
        $fnc = new Fnc1000c();
        $fnc->setWhere($where);
        if(in_array($group, ['day', 'month', 'year'])){
            $filter_type = request()->param('filter_type');
            list($sets,$count) = $fnc->getFinanceSetsGroup($page,$num, $group, $filter_type);
        }
        else{
            list($sets,$count) = $fnc->
                search([$ss['super_search']])->getFinanceSets($page,$num);
        }
        return $this->FeekMsg([
            'result' => $sets,
            'page'   => $page,
            'num'   => $num,
            'count' => $count
        ]);
    }

    /**
     * 账单搜索
     */
    public function search(){
        $check = $this->needLoginNet($uid);
        if($check) return $check;
        $num = 50;$where = false; $bind = [];
        $search = request()->param('search');
        if($search) $search = trim($search);
        // 前缀匹配
        if(substr_count($search,'=') > 0){
            $idx = strpos($search,'=');
            $type = substr($search,0,$idx - 1);
            $template = [
                'mc' => 'a.name',
                'm'   => 'a.name',
                'rq' => 'a.date',
                'r'   => 'a.date',
                'ms' => 'a.descrip',
                'je' => 'a.money',
                'j' => 'a.money'
            ];
            $value = substr($search,$idx+1);
            if(isset($template[$type])){
                $value = strtolower($value);
                $where = 'lower('.$template[$type].') like :v_search';
                $bind['v_search'] = "%$value%";
            }
        }
        // 金额支持： <20,=<20,
        elseif (preg_match('/[\<\>=]+[\d.]/',$search)){
            preg_match('/[\d.]+/',$search,$match);
            $value = count($match)>0 && !empty($match[0])? $match[0]:'';
            $value = trim($value);
            if($value){
                $value = strtolower($value);
                $where = 'lower(a.money) '. str_replace($value,'',$search). ' :v_search';
                $bind['v_search'] = "$value";
            }
            else{
                $search = strtolower($search);
                $where = 'lower(a.name) like :v_search';
                $bind['v_search'] = '%'.$search.'%';
            }
        }
        // 为全数字时自动匹配为金额
        elseif (preg_match('/[\d.]/',$search)){
            $search = strtolower($search);
            $where = 'lower(a.money) like :v_search';
            $bind['v_search'] = "%$search%";
        }
        else{
            $search = strtolower($search);
            $where = 'lower(a.name) like :v_search';
            $bind['v_search'] = '%'.$search.'%';
        }
        $fnc = new Fnc1000c;
        $fnc1 = new Fnc1001c;
        $subSql = $fnc1->field('count(*)')->where('`src_no` = `a`.`no`')->buildSql();
        $data = $fnc
            ->alias('a')
            ->field(['a.*',$subSql=>'detail_ctt','DATE_FORMAT(date,\'%w\') as week'])
            ->where('a.uid',$uid)
            ->where($where)
            ->bind($bind)
            ->order('a.date desc,a.mtime desc')
            ->limit($num)
            ->select()
        ;
        $count = $fnc
            ->alias('a')
            ->where('a.uid',$uid)
            ->where($where)
            ->bind($bind)
            ->count();
        ;
        return $this->FeekMsg([
            'result' => $data,
            'count' => $count
        ]);
        return $data;
    }
}